package com.ganzi.manager.shiro.redis;

import com.ganzi.manager.model.Permissions;
import com.ganzi.manager.model.Role;
import com.ganzi.manager.model.User;
import com.ganzi.manager.service.RoleService;
import com.ganzi.manager.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class MyShiroRealm extends AuthorizingRealm {
    private static Logger log = LoggerFactory.getLogger(MyShiroRealm.class);

    @Autowired
    @Lazy//避免无法使用事物
    private RoleService roleService;

    @Autowired
    @Lazy
    private UserService userService;

    //权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String userName = (String) principals.getPrimaryPrincipal();
        try {
            User user = userService.findUserByName(userName);
            if(user != null){
                List<Role> roles = user.getAllRoles();
                Set<String> roleSet=new HashSet<>();
                Set<String> pemissionSet=new HashSet<>();
                for (Role role : roles) {
                    //如果角色未被锁定就添加角色
                    if(role.getAvailable() == 0){
                        roleSet.add(role.getRoleName());
                        Role tempRole = roleService.findRoleByIdForPermissions(role.getId());
                        if(tempRole != null){
                            List<Permissions> permission = tempRole.getAllPermissions();
                            for (Permissions perm : permission) {
                                //如果权限未被锁定就添加权限
                                if(perm.getAvailable() == 0)pemissionSet.add(perm.getPermission());
                            }
                        }
                    }
                }
                authorizationInfo.setRoles( roleSet );
                authorizationInfo.setStringPermissions(pemissionSet);
            }else{
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return authorizationInfo;
    }

    //登录
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        String username = (String) token.getPrincipal();
        User userInfo = null;
        try {
            userInfo = userService.findUserByName(username);
        } catch (Exception e) {
        }
        if (userInfo == null) {
            throw new UnknownAccountException();//用户不存在
        }
        if (userInfo.getLocked() == 1) {//账户冻结
            throw new LockedAccountException();
        }
        String pass = userInfo.getPassWord();
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userInfo.getId(),
                pass,
                ByteSource.Util.bytes(userInfo.getUserName()+userInfo.getSalt()),
                getName());
        return authenticationInfo;
    }

    //清除当前用户的的 授权缓存
    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }
    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }
    /**
     * 自定义方法：清除所有用户 授权缓存
     */
    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    /**
     * 自定义方法：清除所有用户 认证缓存
     */
    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    /**
     * 自定义方法：清除所有的用户  认证缓存  和 授权缓存
     */
    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }
}
